import $ from 'jquery';

let Ajax = (function ($) {
    const PREFIX = '/monitor';
    function arrangeArguments (url, options) {
        if (typeof url === 'object') {
            options = url;
            if (!('url' in options)) {
                throw new Error ('url not present');
            }
            url = options.url;
            delete options.url;
        }
        options = options || {};

        let headers = options.headers || {}, keys, hasContentType;
        if ('headers' in options) {
            delete options.headers;
        }
        keys = Object.keys (headers);
        for (let name of keys) {
            if (name.toLowerCase () === 'content-type') {
                hasContentType = true;
            }
        }
        if (!hasContentType) {
            headers ['Content-Type'] = 'application/json;charset=utf-8';
        }

        let data = options.data || options;
        return {url, headers, data};
    }

    function rebuildURL2 (url, method, data) {
        url = PREFIX + (url || '');
        method = (method || 'get').toLowerCase ();
        if (!data) return url;
        if (method === 'get') {
            return url;
        } else if (method === 'delete') {
            let s = '', k;
            for (k in data) if (data.hasOwnProperty (k)) {
                if (s.length) s += '&';
                s += k + '=' + encodeURIComponent (data[k]);
            }

            if (s) {
                if (url.includes ('?')) {
                    s = url + '&' + s;
                } else {
                    s = url + '?' + s;
                }
                return s;
            }
            return url;
        } else {
            let reg = /\$\{(.*?)}/g;
            if (reg.test (url)) {
                if (typeof data === 'string') {
                    return url.replace (reg, data);
                } else if (typeof data === 'object') {
                    return url.replace (reg, (matcher, name) => (name in data) ? data[name] : name);
                }
            }
            return url;
        }
    }

    function getAlarmPanel (message, code, callback) {
        let panel = $('#__alarm_panel__');
        if (!panel.length) {
            panel = $('<div id="__alarm_panel__"/>').appendTo ($(document.body)).css ({
                zIndex: 9999, backgroundColor: '#2b2b2b77',
                position: 'fixed', left: 0, top: 0,
                width: '100%', height: '100%', display: 'none',
                alignItems: 'center', justifyItems: 'center'
            });
            $('            <div style="width: fit-content; background-color: #fff; margin: 140px auto">\n' +
                '                <div class="flexable v-top p-20 text-danger">\n' +
                '                    <i class="fa-solid fa-triangle-exclamation ph-10" style="font-size: 2em"></i>\n' +
                '                    <div class="ml-20">\n' +
                '                        <div style="font-size: large" id="__forbidden__">您没有执行这个操作的权限，请联系管理人员</div>\n' +
                '                        <div class="ph-10" style="font-size: large" id="__permission_name__"></div>\n' +
                '                    </div>\n' +
                '                </div>\n' +
                '                <div class="pb-10 pv-20 text-right">\n' +
                '                    <a class="el-button el-button--danger" id="__close_btn__">确定</a>\n' +
                '                </div>\n' +
                '            </div>').appendTo (panel);
            panel.find ('#__close_btn__').on ('click', () => {
                panel.fadeOut (() => {
                    if (callback) callback ();
                });
            });

            if (code === 401) { // 未登录
                panel.find ('#__forbidden__').hide ();
            } else {            // 没权限
                panel.find ('#__forbidden__').show ();
            }

            panel.find ('#__permission_name__').html (
                message || '&nbsp;'
            );
        }
        return panel;
    }

    function doRequest (_url, method, options) {
        let {url, headers, data} = arrangeArguments (_url, options);
        url = rebuildURL2 (url, method, data);

        if (url && url.length >= 1000) {
            throw "URL TOO LONG";
        }

        return new Promise ((resolve, reject) => {
            if (data && ('post' === method || 'put' === method)) {
                if (headers['Content-Type'] === 'application/json;charset=utf-8') {
                    data = JSON.stringify (data);
                }
            }
            let opts = {
                url, data, headers, method, type: 'json'
            };
            $.ajax (opts).done (res => {
                if (typeof res === 'string') {
                    res = JSON.parse (res);
                }
                if ('login_expire' in res) {
                    // 登录已超时
                    getAlarmPanel (res.message, 401, () => {
                        window.location.assign ('/#/login');
                    }).fadeIn ();
                } else if (('permission' in res) && !res.permission) {
                    // 没有权限
                    getAlarmPanel (res.message).fadeIn ();
                } else if ('code' in res) {
                    let code = res.code;

                    switch (code) {
                        case 0:
                            if ('payload' in res) {
                                resolve (res.payload);
                            } else {
                                resolve (res);
                            }
                            break;

                        case 401:
                            // 未登录
                            getAlarmPanel ('您尚未登录，或登录信息已超时，请重新登录', code, () => {
                                window.location.assign ('/#/login');
                            }).fadeIn ();
                            break;

                        case 403:
                            // 没有权限
                            getAlarmPanel (res.message).fadeIn ();
                            break;

                        default:
                            reject ({error: res.message});
                    }
                } else {
                    resolve (res);
                }
            }).fail ((xhr, status, error) => {
                reject ({xhr, status, error});
            })
        });
    }

    return {
        PREFIX,
        get : function (url, params) {
            return doRequest (url, 'get', params);
        },
        post : function (url, params) {
            return doRequest (url, 'post', params);
        },
        put : function (url, params) {
            return doRequest (url, 'put', params);
        },
        delete: function (url, params) {
            return doRequest (url, 'delete', params);
        }
    };
})($);

export default Ajax;